﻿// Copyright 2009 Mike Geise
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace Falcon.Forums.Controllers
{
	using System.Web.Mvc;
	using Falcon.Core.Controllers;
	using Falcon.Core.Extensions;
	using Falcon.Core.Validation;
	using Falcon.Forums.Domain;
	using Falcon.Forums.Domain.Extensions;
	using Falcon.Forums.Domain.Services;
	using Falcon.Forums.Domain.Values;
	using Falcon.Forums.ViewModels;

	[Authorize]
	public class SystemForumPermissionController : DefaultController
	{
		public SystemForumPermissionController(
			IForumService forumService, 
			IForumPermissionService forumPermissionService)
		{
			this.ForumService = forumService;
			this.ForumPermissionService = forumPermissionService;
		}

		public IForumService ForumService
		{
			get; 
			private set;
		}

		public IForumPermissionService ForumPermissionService
		{
			get; 
			private set;
		}

		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Index()
		{
			var forums = ForumService.GetAll(new ForumSpecification { SkipPermissions = true });
			var permission = ForumPermissionService.Create();

			return permission.CanView ? View(Views.Index, Masters.System, forums) : NotAuthorized();
		}

		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Create(int id)
		{
			var permission = ForumPermissionService.Create();

			if (!permission.CanCreate)
			{
				return NotAuthorized();
			}

			var forum = ForumService.GetById(id);

			if (forum == null)
			{
				return Error(ForumsResources.Messages.ForumNotFound);
			}

			var model = new ForumPermissionViewModel
			{
				ForumId = forum.Id
			};

			return View(Views.Create, Masters.System, model);
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Create(ForumPermissionCreate value)
		{
			try
			{
				var permission = ForumPermissionService.Create();

				if (!permission.CanCreate)
				{
					return NotAuthorized();
				}

				var forum = ForumService.GetById(value.ForumId);

				if (forum == null)
				{
					return Error(ForumsResources.Messages.ForumNotFound);
				}

				ForumPermissionService.Insert(permission, value);

				return RedirectToRoute(ForumsRoutes.SystemForumPermissionUpdate, new { id = permission.Id });
			}
			catch (ValidationException exception)
			{
				ModelState.CopyValidationExceptions(exception);
			}

			var model = new ForumPermissionViewModel
			{
				ForumId = value.ForumId
			};

			return View(Views.Create, Masters.System, model);
		}

		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Update(int id)
		{
			var permission = ForumPermissionService.GetById(id);

			if (permission == null)
			{
				return Error(ForumsResources.Messages.ForumPermissionNotFound);
			}

			if (!permission.CanUpdate)
			{
				return NotAuthorized();
			}

			var forum = ForumService.GetById(permission.ForumId);

			if (forum == null)
			{
				return Error(ForumsResources.Messages.ForumNotFound);
			}

			var model = new ForumPermissionViewModel
			{
				Id = permission.Id,
				Forum = forum,
				Role = permission.Role,
				Permissions = forum.Permissions.GroupByRole()
			};

			return View(Views.Update, Masters.System, model);
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Update(ForumPermissionUpdate value)
		{
			try
			{
				var permission = ForumPermissionService.GetById(value.Id);

				if (permission == null)
				{
					return Error(ForumsResources.Messages.ForumPermissionNotFound);
				}

				if (!permission.CanUpdate)
				{
					return NotAuthorized();
				}

				ForumPermissionService.Update(permission, value);

				return RedirectToRoute(ForumsRoutes.SystemForumPermissionUpdate, new { id = permission.Id });
			}
			catch (ValidationException exception)
			{
				ModelState.CopyValidationExceptions(exception);
			}

			return View(Views.Update, Masters.System, value);
		}

		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Delete(int id)
		{
			var permission = ForumPermissionService.GetById(id);

			if (permission == null)
			{
				return Error(ForumsResources.Messages.ForumPermissionNotFound);
			}

			if (!permission.CanDelete)
			{
				return NotAuthorized();
			}

			var forum = ForumService.GetById(permission.ForumId);

			return forum != null ? View(Views.Delete, Masters.System, new ForumPermissionDelete(forum, permission)) : Error(ForumsResources.Messages.ForumNotFound);
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Delete(ForumPermissionDelete value)
		{
			try
			{
				var permission = ForumPermissionService.GetById(value.Id);

				if (permission == null)
				{
					return Error(ForumsResources.Messages.ForumPermissionNotFound);
				}

				if (!permission.CanDelete)
				{
					return NotAuthorized();
				}

				var forum = ForumService.GetById(permission.ForumId);

				if (forum == null)
				{
					return Error(ForumsResources.Messages.ForumNotFound);
				}

				value.Forum = forum;

				ForumPermissionService.Delete(permission);

				return RedirectToRoute(ForumsRoutes.SystemForumPermissionIndex);
			}
			catch (ValidationException exception)
			{
				ModelState.CopyValidationExceptions(exception);
			}

			return View(Views.Delete, Masters.System, value);
		}
	}
}